package com.gitee.apanlh.util.image;

import com.gitee.apanlh.exp.StreamWriteException;
import com.gitee.apanlh.util.check.CheckImport;
import com.gitee.apanlh.util.check.CheckLibrary;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;

/**	
 * 	生成二维码
 *
 * 	@author Pan
 */
public class ImageQrCodeUtils {
	
	static {
		CheckImport.library(CheckLibrary.QRCODE);
	}
	
	/**
	 * 	默认宽
	 * 	<br>默认宽
	 * 	<br>默认字体颜色
	 * 	<br>默认背景颜色
	 */
	private static final int DEFAULT_WIDTH = 400;
	private static final int DEFAULT_HEIGHT = 400;
	private static final int DEFAULT_FRONT_COLOR = 0x000000;
	private static final int DEFAULT_BACKGROUND_COLOR = 0xFFFFFF;
	
	/**
	 * 	构造函数
	 * 
	 * 	@author Pan
	 */
	private ImageQrCodeUtils() {
		//	不允许外部实例
		super();
	}
	
	/**	
	 * 	生成二维码图片
	 * 	<br>默认400宽高
	 * 	<br>返回文件名
	 * 	
	 * 	@author Pan
	 * 	@param  qrCodeContent	二维码内容
	 * 	@param  filePath		文件目录
	 * 	@param  fileName		文件名称
	 * 	@return boolean
	 */
	public static String generateQrCode(String qrCodeContent, String filePath, String fileName) {
		/*
		* 	com.google.zxing.EncodeHintType：编码提示类型,枚举类型
	    * 	EncodeHintType.CHARACTER_SET：设置字符编码类型
	    * 	EncodeHintType.ERROR_CORRECTION：设置误差校正
	    * 	ErrorCorrectionLevel：误差校正等级，L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
	    * 	不设置时，默认为 L 等级，等级不一样，生成的图案不同，但扫描的结果是一样的
	    * 	EncodeHintType.MARGIN：设置二维码边距，单位像素，值越小，二维码距离四周越近
	    */
        Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
        hints.put(EncodeHintType.CHARACTER_SET, CharsetCode.UTF_8);
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 1);
        
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		BitMatrix bitMatrix = null;

		try {
			bitMatrix = multiFormatWriter.encode(qrCodeContent, BarcodeFormat.QR_CODE, DEFAULT_WIDTH, DEFAULT_HEIGHT, hints);
		} catch (Exception e) {
			throw new StreamWriteException(e.getMessage(), e);
		}

		BufferedImage bufferedImage = new BufferedImage(DEFAULT_WIDTH, DEFAULT_HEIGHT, BufferedImage.TYPE_INT_BGR);
    	for (int x = 0; x < DEFAULT_WIDTH; x++) {
    		for (int y = 0; y < DEFAULT_HEIGHT; y++) {
    			bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? DEFAULT_FRONT_COLOR : DEFAULT_BACKGROUND_COLOR);
    		}
    	}
    	return ImageUtils.writeFile(bufferedImage, filePath + fileName);
	}
}
